1 module directx.d2d1_1helper; 2 /*=========================================================================*\ 3 4 Copyright (c) Microsoft Corporation. All rights reserved. 5 6 File: D2D1_1Helper.h 7 8 Module Name: D2D 9 10 Description: Helper files over the D2D interfaces and APIs. 11 12 \*=========================================================================*/ 13 14 version(Windows): 15 16 version(Direct2D_1_3) 17 version = Direct2D_1_2; 18 version(Direct2D_1_2) 19 version = Direct2D_1_1; 20 version(Direct2D_1_1): 21 version = Direct2D_1_0; 22 23 version(DirectWrite): 24 version(WinCodec): 25 version(Direct2D_1_1): 26 27 28 public import directx.d2d1_1; 29 import directx.d2d1helper; 30 31 template TypeTraits(T : INT32) 32 { 33 alias Point = D2D1_POINT_2L; 34 alias Rect = D2D1_RECT_L; 35 } 36 37 template TypeTraits(T : LONG) 38 { 39 alias Point = D2D1_POINT_2L; 40 alias Rect = D2D1_RECT_L; 41 } 42 43 struct Matrix4x3F // : D2D1_MATRIX_4X3_F 44 { 45 D2D1_MATRIX_4X3_F matrix; 46 alias matrix this; 47 48 nothrow this(D2D1_MATRIX_4X3_F m) { matrix = m; } 49 nothrow this( 50 FLOAT m11, FLOAT m12, FLOAT m13, 51 FLOAT m21, FLOAT m22, FLOAT m23, 52 FLOAT m31, FLOAT m32, FLOAT m33, 53 FLOAT m41, FLOAT m42, FLOAT m43 54 ) 55 { 56 _11 = m11; 57 _12 = m12; 58 _13 = m13; 59 60 _21 = m21; 61 _22 = m22; 62 _23 = m23; 63 64 _31 = m31; 65 _32 = m32; 66 _33 = m33; 67 68 _41 = m41; 69 _42 = m42; 70 _43 = m43; 71 } 72 73 // this() 74 /// Use this instead of default constructor 75 static @property nothrow Identity() 76 { 77 return Matrix4x3F( 78 1, 0, 0, 79 0, 1, 0, 80 0, 0, 1, 81 0, 0, 0 82 ); 83 } 84 } 85 86 struct Matrix4x4F // : public D2D1_MATRIX_4X4_F 87 { 88 D2D1_MATRIX_4X4_F matrix; 89 alias matrix this; 90 91 nothrow this(D2D1_MATRIX_4X4_F m) { matrix = m; } 92 nothrow this( 93 FLOAT m11, FLOAT m12, FLOAT m13, FLOAT m14, 94 FLOAT m21, FLOAT m22, FLOAT m23, FLOAT m24, 95 FLOAT m31, FLOAT m32, FLOAT m33, FLOAT m34, 96 FLOAT m41, FLOAT m42, FLOAT m43, FLOAT m44 97 ) 98 { 99 _11 = m11; 100 _12 = m12; 101 _13 = m13; 102 _14 = m14; 103 104 _21 = m21; 105 _22 = m22; 106 _23 = m23; 107 _24 = m24; 108 109 _31 = m31; 110 _32 = m32; 111 _33 = m33; 112 _34 = m34; 113 114 _41 = m41; 115 _42 = m42; 116 _43 = m43; 117 _44 = m44; 118 } 119 120 // this() 121 /// Use this instead of default constructor 122 static nothrow @property Identity() 123 { 124 return Matrix4x4F( 125 1, 0, 0, 0, 126 0, 1, 0, 0, 127 0, 0, 1, 0, 128 0, 0, 0, 1 129 ); 130 } 131 132 bool opEquals( 133 const Matrix4x4F r 134 ) const 135 { 136 return _11 == r._11 && _12 == r._12 && _13 == r._13 && _14 == r._14 && 137 _21 == r._21 && _22 == r._22 && _23 == r._23 && _24 == r._24 && 138 _31 == r._31 && _32 == r._32 && _33 == r._33 && _34 == r._34 && 139 _41 == r._41 && _42 == r._42 && _43 == r._43 && _44 == r._44; 140 } 141 142 static 143 Matrix4x4F 144 Translation(FLOAT x, FLOAT y, FLOAT z) 145 { 146 Matrix4x4F translation; 147 148 translation._11 = 1.0; translation._12 = 0.0; translation._13 = 0.0; translation._14 = 0.0; 149 translation._21 = 0.0; translation._22 = 1.0; translation._23 = 0.0; translation._24 = 0.0; 150 translation._31 = 0.0; translation._32 = 0.0; translation._33 = 1.0; translation._34 = 0.0; 151 translation._41 = x; translation._42 = y; translation._43 = z; translation._44 = 1.0; 152 153 return translation; 154 } 155 156 static 157 Matrix4x4F 158 Scale(FLOAT x, FLOAT y, FLOAT z) 159 { 160 Matrix4x4F scale; 161 162 scale._11 = x; scale._12 = 0.0; scale._13 = 0.0; scale._14 = 0.0; 163 scale._21 = 0.0; scale._22 = y; scale._23 = 0.0; scale._24 = 0.0; 164 scale._31 = 0.0; scale._32 = 0.0; scale._33 = z; scale._34 = 0.0; 165 scale._41 = 0.0; scale._42 = 0.0; scale._43 = 0.0; scale._44 = 1.0; 166 167 return scale; 168 } 169 170 static 171 Matrix4x4F 172 RotationX(FLOAT degreeX) 173 { 174 FLOAT angleInRadian = degreeX * (3.141592654f / 180.0f); 175 176 FLOAT sinAngle = 0.0; 177 FLOAT cosAngle = 0.0; 178 D2D1SinCos(angleInRadian, &sinAngle, &cosAngle); 179 180 return Matrix4x4F( 181 1, 0, 0, 0, 182 0, cosAngle, sinAngle, 0, 183 0, -sinAngle, cosAngle, 0, 184 0, 0, 0, 1 185 ); 186 } 187 188 static 189 Matrix4x4F 190 RotationY(FLOAT degreeY) 191 { 192 FLOAT angleInRadian = degreeY * (3.141592654f / 180.0f); 193 194 FLOAT sinAngle = 0.0; 195 FLOAT cosAngle = 0.0; 196 D2D1SinCos(angleInRadian, &sinAngle, &cosAngle); 197 198 return Matrix4x4F( 199 cosAngle, 0, -sinAngle, 0, 200 0, 1, 0, 0, 201 sinAngle, 0, cosAngle, 0, 202 0, 0, 0, 1 203 ); 204 } 205 206 static 207 Matrix4x4F 208 RotationZ(FLOAT degreeZ) 209 { 210 FLOAT angleInRadian = degreeZ * (3.141592654f / 180.0f); 211 212 FLOAT sinAngle = 0.0; 213 FLOAT cosAngle = 0.0; 214 D2D1SinCos(angleInRadian, &sinAngle, &cosAngle); 215 216 return Matrix4x4F( 217 cosAngle, sinAngle, 0, 0, 218 -sinAngle, cosAngle, 0, 0, 219 0, 0, 1, 0, 220 0, 0, 0, 1 221 ); 222 } 223 224 // 225 // 3D Rotation matrix for an arbitrary axis specified by x, y and z 226 // 227 static 228 Matrix4x4F 229 RotationArbitraryAxis(FLOAT x, FLOAT y, FLOAT z, FLOAT degree) 230 { 231 // Normalize the vector represented by x, y, and z 232 FLOAT magnitude = D2D1Vec3Length(x, y, z); 233 x /= magnitude; 234 y /= magnitude; 235 z /= magnitude; 236 237 FLOAT angleInRadian = degree * (3.141592654f / 180.0f); 238 239 FLOAT sinAngle = 0.0; 240 FLOAT cosAngle = 0.0; 241 D2D1SinCos(angleInRadian, &sinAngle, &cosAngle); 242 243 FLOAT oneMinusCosAngle = 1 - cosAngle; 244 245 return Matrix4x4F( 246 1 + oneMinusCosAngle * (x * x - 1), 247 z * sinAngle + oneMinusCosAngle * x * y, 248 -y * sinAngle + oneMinusCosAngle * x * z, 249 0, 250 251 -z * sinAngle + oneMinusCosAngle * y * x, 252 1 + oneMinusCosAngle * (y * y - 1), 253 x * sinAngle + oneMinusCosAngle * y * z, 254 0, 255 256 y * sinAngle + oneMinusCosAngle * z * x, 257 -x * sinAngle + oneMinusCosAngle * z * y, 258 1 + oneMinusCosAngle * (z * z - 1) , 259 0, 260 261 0, 0, 0, 1 262 ); 263 } 264 265 static 266 Matrix4x4F 267 SkewX(FLOAT degreeX) 268 { 269 FLOAT angleInRadian = degreeX * (3.141592654f / 180.0f); 270 271 FLOAT tanAngle = D2D1Tan(angleInRadian); 272 273 return Matrix4x4F( 274 1, 0, 0, 0, 275 tanAngle, 1, 0, 0, 276 0, 0, 1, 0, 277 0, 0, 0, 1 278 ); 279 } 280 281 static 282 Matrix4x4F 283 SkewY(FLOAT degreeY) 284 { 285 FLOAT angleInRadian = degreeY * (3.141592654f / 180.0f); 286 287 FLOAT tanAngle = D2D1Tan(angleInRadian); 288 289 return Matrix4x4F( 290 1, tanAngle, 0, 0, 291 0, 1, 0, 0, 292 0, 0, 1, 0, 293 0, 0, 0, 1 294 ); 295 } 296 297 298 static 299 Matrix4x4F 300 PerspectiveProjection(FLOAT depth) 301 { 302 float proj = 0; 303 304 if (depth > 0) 305 { 306 proj = -1/depth; 307 } 308 309 return Matrix4x4F( 310 1, 0, 0, 0, 311 0, 1, 0, 0, 312 0, 0, 1, proj, 313 0, 0, 0, 1 314 ); 315 } 316 317 // 318 // Functions for convertion from the base D2D1_MATRIX_4X4_f to 319 // this type without making a copy 320 // 321 static 322 const(Matrix4x4F)* 323 ReinterpretBaseType(const(D2D1_MATRIX_4X4_F)* pMatrix) 324 { 325 return cast(const(Matrix4x4F)*)pMatrix; 326 } 327 328 static 329 nothrow 330 Matrix4x4F* 331 ReinterpretBaseType(D2D1_MATRIX_4X4_F *pMatrix) 332 { 333 return cast(Matrix4x4F*)(pMatrix); 334 } 335 336 nothrow 337 FLOAT 338 Determinant() const 339 { 340 FLOAT minor1 = _41 * (_12 * (_23 * _34 - _33 * _24) - _13 * (_22 * _34 - _24 * _32) + _14 * (_22 * _33 - _23 * _32)); 341 FLOAT minor2 = _42 * (_11 * (_21 * _34 - _31 * _24) - _13 * (_21 * _34 - _24 * _31) + _14 * (_21 * _33 - _23 * _31)); 342 FLOAT minor3 = _43 * (_11 * (_22 * _34 - _32 * _24) - _12 * (_21 * _34 - _24 * _31) + _14 * (_21 * _32 - _22 * _31)); 343 FLOAT minor4 = _44 * (_11 * (_22 * _33 - _32 * _23) - _12 * (_21 * _33 - _23 * _31) + _13 * (_21 * _32 - _22 * _31)); 344 345 return minor1 - minor2 + minor3 - minor4; 346 } 347 348 nothrow 349 bool 350 IsIdentity() const 351 { 352 return _11 == 1.0f && _12 == 0.0f && _13 == 0.0f && _14 == 0.0f 353 && _21 == 0.0f && _22 == 1.0f && _23 == 0.0f && _24 == 0.0f 354 && _31 == 0.0f && _32 == 0.0f && _33 == 1.0f && _34 == 0.0f 355 && _41 == 0.0f && _42 == 0.0f && _43 == 0.0f && _44 == 1.0f; 356 } 357 358 nothrow 359 void 360 SetProduct(const Matrix4x4F a, const Matrix4x4F b) 361 { 362 _11 = a._11 * b._11 + a._12 * b._21 + a._13 * b._31 + a._14 * b._41; 363 _12 = a._11 * b._12 + a._12 * b._22 + a._13 * b._32 + a._14 * b._42; 364 _13 = a._11 * b._13 + a._12 * b._23 + a._13 * b._33 + a._14 * b._43; 365 _14 = a._11 * b._14 + a._12 * b._24 + a._13 * b._34 + a._14 * b._44; 366 367 _21 = a._21 * b._11 + a._22 * b._21 + a._23 * b._31 + a._24 * b._41; 368 _22 = a._21 * b._12 + a._22 * b._22 + a._23 * b._32 + a._24 * b._42; 369 _23 = a._21 * b._13 + a._22 * b._23 + a._23 * b._33 + a._24 * b._43; 370 _24 = a._21 * b._14 + a._22 * b._24 + a._23 * b._34 + a._24 * b._44; 371 372 _31 = a._31 * b._11 + a._32 * b._21 + a._33 * b._31 + a._34 * b._41; 373 _32 = a._31 * b._12 + a._32 * b._22 + a._33 * b._32 + a._34 * b._42; 374 _33 = a._31 * b._13 + a._32 * b._23 + a._33 * b._33 + a._34 * b._43; 375 _34 = a._31 * b._14 + a._32 * b._24 + a._33 * b._34 + a._34 * b._44; 376 377 _41 = a._41 * b._11 + a._42 * b._21 + a._43 * b._31 + a._44 * b._41; 378 _42 = a._41 * b._12 + a._42 * b._22 + a._43 * b._32 + a._44 * b._42; 379 _43 = a._41 * b._13 + a._42 * b._23 + a._43 * b._33 + a._44 * b._43; 380 _44 = a._41 * b._14 + a._42 * b._24 + a._43 * b._34 + a._44 * b._44; 381 } 382 383 nothrow 384 Matrix4x4F 385 opBinary(string op)(const Matrix4x4F matrix) const if(op == "*") 386 { 387 Matrix4x4F result; 388 389 result.SetProduct(*this, matrix); 390 391 return result; 392 } 393 } 394 395 396 struct Matrix5x4F // : D2D1_MATRIX_5X4_F 397 { 398 D2D1_MATRIX_5X4_F matrix; 399 alias matrix this; 400 401 nothrow this(D2D1_MATRIX_5X4_F m) { matrix = m; } 402 nothrow this( 403 FLOAT m11, FLOAT m12, FLOAT m13, FLOAT m14, 404 FLOAT m21, FLOAT m22, FLOAT m23, FLOAT m24, 405 FLOAT m31, FLOAT m32, FLOAT m33, FLOAT m34, 406 FLOAT m41, FLOAT m42, FLOAT m43, FLOAT m44, 407 FLOAT m51, FLOAT m52, FLOAT m53, FLOAT m54 408 ) 409 { 410 _11 = m11; 411 _12 = m12; 412 _13 = m13; 413 _14 = m14; 414 415 _21 = m21; 416 _22 = m22; 417 _23 = m23; 418 _24 = m24; 419 420 _31 = m31; 421 _32 = m32; 422 _33 = m33; 423 _34 = m34; 424 425 _41 = m41; 426 _42 = m42; 427 _43 = m43; 428 _44 = m44; 429 430 _51 = m51; 431 _52 = m52; 432 _53 = m53; 433 _54 = m54; 434 } 435 436 // this() 437 /// Use this instead of default constructor 438 static nothrow @property Identity() 439 { 440 return Matrix5x4F( 441 1, 0, 0, 0, 442 0, 1, 0, 0, 443 0, 0, 1, 0, 444 0, 0, 0, 1, 445 0, 0, 0, 0 446 ); 447 } 448 } 449 450 D2D1_COLOR_F 451 ConvertColorSpace( 452 D2D1_COLOR_SPACE sourceColorSpace, 453 D2D1_COLOR_SPACE destinationColorSpace, 454 const D2D1_COLOR_F color 455 ) 456 { 457 return D2D1ConvertColorSpace( 458 sourceColorSpace, 459 destinationColorSpace, 460 &color 461 ); 462 } 463 464 D2D1_DRAWING_STATE_DESCRIPTION1 465 DrawingStateDescription1( 466 D2D1_ANTIALIAS_MODE antialiasMode = D2D1_ANTIALIAS_MODE_PER_PRIMITIVE, 467 D2D1_TEXT_ANTIALIAS_MODE textAntialiasMode = D2D1_TEXT_ANTIALIAS_MODE_DEFAULT, 468 D2D1_TAG tag1 = 0, 469 D2D1_TAG tag2 = 0, 470 const D2D1_MATRIX_3X2_F transform = D2D1.IdentityMatrix(), 471 D2D1_PRIMITIVE_BLEND primitiveBlend = D2D1_PRIMITIVE_BLEND_SOURCE_OVER, 472 D2D1_UNIT_MODE unitMode = D2D1_UNIT_MODE_DIPS 473 ) 474 { 475 D2D1_DRAWING_STATE_DESCRIPTION1 drawingStateDescription1; 476 477 drawingStateDescription1.antialiasMode = antialiasMode; 478 drawingStateDescription1.textAntialiasMode = textAntialiasMode; 479 drawingStateDescription1.tag1 = tag1; 480 drawingStateDescription1.tag2 = tag2; 481 drawingStateDescription1.transform = transform; 482 drawingStateDescription1.primitiveBlend = primitiveBlend; 483 drawingStateDescription1.unitMode = unitMode; 484 485 return drawingStateDescription1; 486 } 487 488 D2D1_DRAWING_STATE_DESCRIPTION1 489 DrawingStateDescription1( 490 const D2D1_DRAWING_STATE_DESCRIPTION desc, 491 D2D1_PRIMITIVE_BLEND primitiveBlend = D2D1_PRIMITIVE_BLEND_SOURCE_OVER, 492 D2D1_UNIT_MODE unitMode = D2D1_UNIT_MODE_DIPS 493 ) 494 { 495 D2D1_DRAWING_STATE_DESCRIPTION1 drawingStateDescription1; 496 497 drawingStateDescription1.antialiasMode = desc.antialiasMode; 498 drawingStateDescription1.textAntialiasMode = desc.textAntialiasMode; 499 drawingStateDescription1.tag1 = desc.tag1; 500 drawingStateDescription1.tag2 = desc.tag2; 501 drawingStateDescription1.transform = desc.transform; 502 drawingStateDescription1.primitiveBlend = primitiveBlend; 503 drawingStateDescription1.unitMode = unitMode; 504 505 return drawingStateDescription1; 506 } 507 508 D2D1_BITMAP_PROPERTIES1 509 BitmapProperties1( 510 D2D1_BITMAP_OPTIONS bitmapOptions = D2D1_BITMAP_OPTIONS_NONE, 511 const D2D1_PIXEL_FORMAT pixelFormat = D2D1.PixelFormat(), 512 FLOAT dpiX = 96.0f, 513 FLOAT dpiY = 96.0f, 514 ID2D1ColorContext colorContext = null 515 ) 516 { 517 D2D1_BITMAP_PROPERTIES1 bitmapProperties = 518 { 519 pixelFormat, 520 dpiX, dpiY, 521 bitmapOptions, 522 colorContext 523 }; 524 525 return bitmapProperties; 526 } 527 528 D2D1_LAYER_PARAMETERS1 529 LayerParameters1( 530 const D2D1_RECT_F contentBounds = D2D1.InfiniteRect(), 531 ID2D1Geometry geometricMask = NULL, 532 D2D1_ANTIALIAS_MODE maskAntialiasMode = D2D1_ANTIALIAS_MODE_PER_PRIMITIVE, 533 D2D1_MATRIX_3X2_F maskTransform = D2D1.IdentityMatrix(), 534 FLOAT opacity = 1.0, 535 ID2D1Brush opacityBrush = NULL, 536 D2D1_LAYER_OPTIONS1 layerOptions = D2D1_LAYER_OPTIONS1_NONE 537 ) 538 { 539 D2D1_LAYER_PARAMETERS1 layerParameters; 540 541 layerParameters.contentBounds = contentBounds; 542 layerParameters.geometricMask = geometricMask; 543 layerParameters.maskAntialiasMode = maskAntialiasMode; 544 layerParameters.maskTransform = maskTransform; 545 layerParameters.opacity = opacity; 546 layerParameters.opacityBrush = opacityBrush; 547 layerParameters.layerOptions = layerOptions; 548 549 return layerParameters; 550 } 551 552 D2D1_STROKE_STYLE_PROPERTIES1 553 StrokeStyleProperties1( 554 D2D1_CAP_STYLE startCap = D2D1_CAP_STYLE_FLAT, 555 D2D1_CAP_STYLE endCap = D2D1_CAP_STYLE_FLAT, 556 D2D1_CAP_STYLE dashCap = D2D1_CAP_STYLE_FLAT, 557 D2D1_LINE_JOIN lineJoin = D2D1_LINE_JOIN_MITER, 558 FLOAT miterLimit = 10.0f, 559 D2D1_DASH_STYLE dashStyle = D2D1_DASH_STYLE_SOLID, 560 FLOAT dashOffset = 0.0f, 561 D2D1_STROKE_TRANSFORM_TYPE transformType = D2D1_STROKE_TRANSFORM_TYPE_NORMAL 562 ) 563 { 564 D2D1_STROKE_STYLE_PROPERTIES1 strokeStyleProperties; 565 566 strokeStyleProperties.startCap = startCap; 567 strokeStyleProperties.endCap = endCap; 568 strokeStyleProperties.dashCap = dashCap; 569 strokeStyleProperties.lineJoin = lineJoin; 570 strokeStyleProperties.miterLimit = miterLimit; 571 strokeStyleProperties.dashStyle = dashStyle; 572 strokeStyleProperties.dashOffset = dashOffset; 573 strokeStyleProperties.transformType = transformType; 574 575 return strokeStyleProperties; 576 } 577 578 D2D1_IMAGE_BRUSH_PROPERTIES 579 ImageBrushProperties( 580 D2D1_RECT_F sourceRectangle, 581 D2D1_EXTEND_MODE extendModeX = D2D1_EXTEND_MODE_CLAMP, 582 D2D1_EXTEND_MODE extendModeY = D2D1_EXTEND_MODE_CLAMP, 583 D2D1_INTERPOLATION_MODE interpolationMode = D2D1_INTERPOLATION_MODE_LINEAR 584 ) 585 { 586 D2D1_IMAGE_BRUSH_PROPERTIES imageBrushProperties; 587 588 imageBrushProperties.extendModeX = extendModeX; 589 imageBrushProperties.extendModeY = extendModeY; 590 imageBrushProperties.interpolationMode = interpolationMode; 591 imageBrushProperties.sourceRectangle = sourceRectangle; 592 593 return imageBrushProperties; 594 } 595 596 D2D1_BITMAP_BRUSH_PROPERTIES1 597 BitmapBrushProperties1( 598 D2D1_EXTEND_MODE extendModeX = D2D1_EXTEND_MODE_CLAMP, 599 D2D1_EXTEND_MODE extendModeY = D2D1_EXTEND_MODE_CLAMP, 600 D2D1_INTERPOLATION_MODE interpolationMode = D2D1_INTERPOLATION_MODE_LINEAR 601 ) 602 { 603 D2D1_BITMAP_BRUSH_PROPERTIES1 bitmapBrush1Properties; 604 605 bitmapBrush1Properties.extendModeX = extendModeX; 606 bitmapBrush1Properties.extendModeY = extendModeY; 607 bitmapBrush1Properties.interpolationMode = interpolationMode; 608 609 return bitmapBrush1Properties; 610 } 611 612 D2D1_PRINT_CONTROL_PROPERTIES 613 PrintControlProperties( 614 D2D1_PRINT_FONT_SUBSET_MODE fontSubsetMode = D2D1_PRINT_FONT_SUBSET_MODE_DEFAULT, 615 FLOAT rasterDpi = 150.0f, 616 D2D1_COLOR_SPACE colorSpace = D2D1_COLOR_SPACE_SRGB 617 ) 618 { 619 D2D1_PRINT_CONTROL_PROPERTIES printControlProps; 620 621 printControlProps.fontSubset = fontSubsetMode; 622 printControlProps.rasterDPI = rasterDpi; 623 printControlProps.colorSpace = colorSpace; 624 625 return printControlProps; 626 } 627 628 D2D1_RENDERING_CONTROLS 629 RenderingControls( 630 D2D1_BUFFER_PRECISION bufferPrecision, 631 D2D1_SIZE_U tileSize 632 ) 633 { 634 D2D1_RENDERING_CONTROLS renderingControls; 635 636 renderingControls.bufferPrecision = bufferPrecision; 637 renderingControls.tileSize = tileSize; 638 639 return renderingControls; 640 } 641 642 D2D1_EFFECT_INPUT_DESCRIPTION 643 EffectInputDescription( 644 ID2D1Effect effect, 645 UINT32 inputIndex, 646 D2D1_RECT_F inputRectangle 647 ) 648 { 649 D2D1_EFFECT_INPUT_DESCRIPTION description; 650 651 description.effect = effect; 652 description.inputIndex = inputIndex; 653 description.inputRectangle = inputRectangle; 654 655 return description; 656 } 657 658 D2D1_CREATION_PROPERTIES 659 CreationProperties( 660 D2D1_THREADING_MODE threadingMode, 661 D2D1_DEBUG_LEVEL debugLevel, 662 D2D1_DEVICE_CONTEXT_OPTIONS options 663 ) 664 { 665 D2D1_CREATION_PROPERTIES creationProperties; 666 667 creationProperties.threadingMode = threadingMode; 668 creationProperties.debugLevel = debugLevel; 669 creationProperties.options = options; 670 671 return creationProperties; 672 } 673 674 D2D1_VECTOR_2F 675 Vector2F( 676 FLOAT x = 0.0f, 677 FLOAT y = 0.0f 678 ) 679 { 680 D2D1_VECTOR_2F vec2 = {x, y}; 681 return vec2; 682 } 683 684 D2D1_VECTOR_3F 685 Vector3F( 686 FLOAT x = 0.0f, 687 FLOAT y = 0.0f, 688 FLOAT z = 0.0f 689 ) 690 { 691 D2D1_VECTOR_3F vec3 = {x, y, z}; 692 return vec3; 693 } 694 695 D2D1_VECTOR_4F 696 Vector4F( 697 FLOAT x = 0.0f, 698 FLOAT y = 0.0f, 699 FLOAT z = 0.0f, 700 FLOAT w = 0.0f 701 ) 702 { 703 D2D1_VECTOR_4F vec4 = {x, y, z, w}; 704 return vec4; 705 } 706 707 D2D1_POINT_2L 708 Point2L( 709 INT32 x = 0, 710 INT32 y = 0 711 ) 712 { 713 return D2D1_POINT_2L(x, y); 714 } 715 716 D2D1_RECT_L 717 RectL( 718 INT32 left = 0, 719 INT32 top = 0, 720 INT32 right = 0, 721 INT32 bottom = 0 722 ) 723 { 724 return D2D1_RECT_L(left, top, right, bottom); 725 } 726 727 /// 728 /// Sets a bitmap as an effect input, while inserting a DPI compensation effect 729 /// to preserve visual appearance as the device context's DPI changes. 730 /// 731 HRESULT 732 SetDpiCompensatedEffectInput( 733 ID2D1DeviceContext deviceContext, 734 ID2D1Effect effect, 735 UINT32 inputIndex, 736 ID2D1Bitmap inputBitmap, 737 D2D1_INTERPOLATION_MODE interpolationMode = D2D1_INTERPOLATION_MODE_LINEAR, 738 D2D1_BORDER_MODE borderMode = D2D1_BORDER_MODE_HARD 739 ) 740 { 741 HRESULT hr = S_OK; 742 ID2D1Effect dpiCompensationEffect = null; 743 744 if (inputBitmap is null) 745 { 746 effect.SetInput(inputIndex, null); 747 return hr; 748 } 749 750 hr = deviceContext.CreateEffect(&CLSID_D2D1DpiCompensation, &dpiCompensationEffect); 751 752 if (SUCCEEDED(hr)) 753 { 754 if (SUCCEEDED(hr)) 755 { 756 dpiCompensationEffect.SetInput(0, inputBitmap); 757 758 D2D1_POINT_2F bitmapDpi; 759 inputBitmap.GetDpi(bitmapDpi.x, bitmapDpi.y); 760 hr = dpiCompensationEffect.SetValue(D2D1_DPICOMPENSATION_PROP_INPUT_DPI, bitmapDpi); 761 } 762 763 if (SUCCEEDED(hr)) 764 { 765 hr = dpiCompensationEffect.SetValue(D2D1_DPICOMPENSATION_PROP_INTERPOLATION_MODE, interpolationMode); 766 } 767 768 if (SUCCEEDED(hr)) 769 { 770 hr = dpiCompensationEffect.SetValue(D2D1_DPICOMPENSATION_PROP_BORDER_MODE, borderMode); 771 } 772 773 if (SUCCEEDED(hr)) 774 { 775 effect.SetInputEffect(inputIndex, dpiCompensationEffect); 776 } 777 778 if (dpiCompensationEffect !is null) 779 { 780 dpiCompensationEffect.Release(); 781 } 782 } 783 784 return hr; 785 }